package com.hmdp.utils;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;


@Component
public class RedisIdWorker {

    /**
     * 开始的时间戳，设定为2025年1月1日 00:00:00 UTC
     * 该时间戳用于生成唯一ID的基准时间，确保ID的有序性和唯一性
     */
    public static final long BEGIN_TIMESTAMP = 1735689600L;

    /**
     * 序列号向左位移的位数
     * 用于将时间戳和序列号合并，确保时间戳在高位，序列号在低位
     */
    public static final long COUNT_BITS = 32;

    /**
     * Redis操作模板，用于操作Redis数据
     */
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 生成全局唯一ID
     *
     * @param keyPrefix ID前缀，用于区分不同的业务场景
     * @return 返回生成的全局唯一ID
     */
    public long globalIDMint(String keyPrefix) {
        // 获取当前时间的UTC时间戳
        LocalDateTime now = LocalDateTime.now();
        long currentSecond = now.toEpochSecond(ZoneOffset.UTC);

        // 计算相对于基准时间（2025年1月1日 00:00:00 UTC）的秒数
        long timeStamp = currentSecond - BEGIN_TIMESTAMP;

        // 生成序列化号
        // 获取当前日期，格式为yyyy-MM-dd
        String date = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));

        // 使用Redis的自增长命令生成序列号，确保每个业务场景每天生成的ID都是唯一的
        // 接收类型使用long而非Long，便于后续进行位运算
        long count = stringRedisTemplate.opsForValue().increment("icr:" + keyPrefix + ":" + date);

        // 将时间戳左移COUNT_BITS位，然后与序列号进行按位或运算，拼接成最终的ID
        return timeStamp << COUNT_BITS | count;
    }
}
//    public static void main(String[] args) {
//        // 设置基准时间2025年1月1日 00:00:00 UTC
//        LocalDateTime time = LocalDateTime.of(2025, 1, 1, 0, 0, 0);
//        // 转换为UTC时间戳
//        long second = time.toEpochSecond(ZoneOffset.UTC);
//        // 输出基准时间的UTC时间戳，并记录为常量
//        System.out.println("基准时间戳（秒）: " + second);
//    }


